﻿namespace WCFMINERP.ComControls
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Windows.Forms;
	using DevExpress.XtraEditors;
	using DevExpress.XtraEditors.Drawing;


	public class FilteComboxEdit : ComboBoxEdit, IDisplaySource {
		public EventHandler<ComboxItemsChangedArgs> ComboxItemsChanged;
		private Func<object, bool> Filter;
		private bool _visblePopup;
		private bool filterEnabled;
		public FilteComboxEdit() {
			EnterSubmit = true;
			VisblePopup = true;
			LostFocusSelectFirst = true;
			Properties.AutoComplete = false;
			Properties.AllowMouseWheel = false;
			FiltedItems = new List<object>();
		}
        protected override void OnClick(EventArgs e)
        {
            this.Text = "";
            base.OnClick(e);
        }

	    public List<object> FiltedItems { get; private set; }
		public bool VisblePopup {
			get { return _visblePopup; }
			set {
				_visblePopup = value;
				for (int i = 0; i < Properties.Buttons.Count; i++) {
					Properties.Buttons[i].Visible = value;
				}
				LostFocusSelectFirst = value;
			}
		}
		public bool LostFocusSelectFirst { get; set; }

		#region IDisplaySource Members

		/// <summary>
		///     原始数据源 所有数据
		/// </summary>
		public DisplayItem[] DisplayItemSource { get; set; }

		#endregion

		/// <summary>
		///     引发 <see cref="E:System.Windows.Forms.Control.LostFocus" /> 事件。
		/// </summary>
		/// <param name="e">包含事件数据的 <see cref="T:System.EventArgs" />。</param>
		protected override void OnLostFocus(EventArgs e) {
			if (Text.Length > 0 && LostFocusSelectFirst) {
				if (!(EditValue is DisplayItem)) {
					if (Properties.Items.Count > 0) {
						EditValue = Properties.Items[0];
					    LostFocusSelectFirst = false;
					}
				}
			}
			base.OnLostFocus(e);
		}
		public bool EnterSubmit { get; set; }
		protected override void OnEditorKeyPress(KeyPressEventArgs e) {
			if (EnterSubmit && Text.Length > 0) {
				if (e.KeyChar == Keys.Enter.ConvertTo<char>()) {
					if (!(EditValue is DisplayItem)) {
						if (Properties.Items.Count > 0) {
							EditValue = Properties.Items[0];
							ClosePopup();
						}
					}
				}
			}
			base.OnEditorKeyPress(e);
		}
		public void SetCustFilter(Func<object, bool> filter, bool enabled) {
			Filter = filter;
			filterEnabled = enabled;
		}
		protected override void OnEditValueChanged() {
			base.OnEditValueChanged();
			FiltedItems.Clear();
			BeginUpdate();
			if (Text.Length > 0)
			{
			    //LostFocusSelectFirst = false;
				if (DisplayItemSource != null) {
					string chinesecap = MnemonicCode.chinesecap(Text);
					DisplayItem[] array =
						DisplayItemSource.Where(
							c =>
                            //c.MnemonicCode.IndexOf(chinesecap, StringComparison.InvariantCultureIgnoreCase) > -1 ||
                            //c.MnemonicCode1.IndexOf(chinesecap, StringComparison.InvariantCultureIgnoreCase) > -1||
                           // c.DisplayField.IndexOf(Text, StringComparison.InvariantCultureIgnoreCase) > -1||
                            c.DisplayField.IndexOf(Text, StringComparison.InvariantCultureIgnoreCase) > -1).ToArray();
					Properties.Items.FillComboBoxItemCollection(array);
				}
			}
			else {
				Properties.Items.FillComboBoxItemCollection(DisplayItemSource);
			}
			foreach(DisplayItem item in Properties.Items) {
				FiltedItems.Add(item.Value);
			}
			DoComboxItemsChanged(FiltedItems);
			if (!IsPopupOpen && CanShowPopup) {
				ShowPopup();
			}
			EndUpdate();
		}
		protected override void DoShowPopup() {
			if (VisblePopup) {
				base.DoShowPopup();
			}
		}
		private void DoComboxItemsChanged(List<object> items) {
			if (ComboxItemsChanged != null) {
				ComboxItemsChangedArgs args = new ComboxItemsChangedArgs();
				args.Items = items;
				ComboxItemsChanged(this, args);
			}
		}
		public void FillDisplayItemCollections<T>(IEnumerable<T> collection, Func<T, string> getDisplayField, Func<T, object> getVal = null,
												Func<T, object> orderby = null) {
			if (orderby == null) {
				orderby = getDisplayField;
			}
			if (getVal == null) {
				getVal = getDisplayField;
			}
			FilteComboxEdit ctrl = this;
			List<DisplayItem> dataSource = null;
			if (ctrl.Properties != null) {
				ctrl.Properties.BeginUpdate();
				dataSource = ctrl.Properties.Items.FillComboBoxItemCollection(collection, getDisplayField, getVal, null, @orderby);
				ctrl.Properties.EndUpdate();
			}
			IDisplaySource displaySource = ctrl;
			if (dataSource != null) {
				displaySource.DisplayItemSource = dataSource.ToArray();
			}
			ClosePopup();
		}
		public void FillDisplayItem_Enum<T>(Func<int, bool> condition = null) {
			EnumItem[] arr = typeof (T).ConvertEnumItem();
			if (condition != null) {
				arr = arr.Where(c => condition(c.Value)).ToArray();
			}
			FillDisplayItemCollections(arr, c => c.Description, c => c.Value, c => c.Description);
		}
		public int GetEnumValue() {
			try {
				DisplayItem displayItem = SelectedItem as DisplayItem;
				if (displayItem != null) {
					return (int) displayItem.Value;
				}
			}
			catch (Exception) {
				return -1;
			}
			return -1;
		}

		#region Overrides of ButtonEdit

		protected override void OnClickButton(EditorButtonObjectInfoArgs buttonInfo) {
			BeginUpdate();
			Properties.Items.FillComboBoxItemCollection(DisplayItemSource);
			EndUpdate();
			DoShowPopup();
		}

		#endregion
	}

	public class ComboxItemsChangedArgs : EventArgs {
		public List<object> Items { get; set; }
	}
}
